/**
 *  Copyright 2011 Marco Berri - marcoberri@gmail.com
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and limitations under the License.
 **/
package com.mbfasttrack.service;

import com.mbfasttrack.model.Like;
import com.mbfasttrack.model.Media;
import com.mbfasttrack.model.User;
import java.util.ArrayList;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.mongodb.core.geo.Distance;
import org.springframework.data.mongodb.core.geo.Metrics;
import org.springframework.data.mongodb.core.geo.Point;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author Marco Berri marcoberri@gmail.com http://tecnicume.blogspot.com
 */
@Service("UserService")
@Transactional
public class UserService extends Base {

    /**
     *  
     * @param user 
     * @return if username or email exist return null
     */
    public User add(User user) {

        try {

            if (userRepository.findOneByUsername(user.getUsername()) != null || userRepository.findOneByEmail(user.getEmail()) != null) {
                log.fatal("User Exist!!");
                return null;
            }

            if (user.getCoordx() != null && user.getCoordy() != null) {
                double[] p = {user.getCoordx(), user.getCoordy()};
                user.setLocationPoint(p);

            }

            return this.save(user);



        } catch (Exception e) {
            log.fatal(e);
            return null;
        }

    }

    /**
     * 
     * @param user
     * @return
     */
    public User save(User user) {

        try {

            User user_cp = userRepository.save(user);
            //caso che arriva l'avatar come file upload
            if (user.getAvatar() != null) {
                Media m = new Media();
                m.setMultipartfile(user.getAvatar());
                m.setType("avatar");
                m.setObjtype("user");
                m.setObjid(user.getId());
                m = mediaService.add(m);
                user_cp.addMedia(m);
                user.setAvatar(null);
                user_cp.setAvatar(null);
                user_cp = userRepository.save(user_cp);
                
            }

            return user_cp;

        } catch (Exception e) {
            log.fatal("Exception:", e);
            return null;
        }

    }

    /**
     * 
     * @param user
     * @param km
     * @return
     */
    public Page<User> getUsersNearMe(User user, int km) {

        try {
            if (user.getLocationPoint() == null || user.getLocationPoint().length != 2) {
                return null;
            }

            Point p = new Point(user.getLocationPoint()[0], user.getLocationPoint()[1]);
            Distance distance = new Distance(km, Metrics.KILOMETERS);
            return userRepository.findByLocationPointNear(p, distance, new PageRequest(0, 10));
        } catch (Exception e) {
            log.fatal(e);
            return null;
        }

    }
    
   public Page<User> getUsersNearMe(String username, int km) {
        
       return getUsersNearMe(userRepository.findOneByUsername(username), km);
    }  

    /**
     *  Sta cosa fa schifo vorrei estrarre dalla like solo quello che mi serve veramente e non un pre-filtro
     * 
     * @param userid
     * @return
     */
    public List<User> findFriendByUserId(String userid) {

        List<Like> list = likeService.findFriendByUserId(userid);

        ArrayList<User> result = new ArrayList<User>();

        for (Like l : list) {
            result.add((User) l.getObj());
        }

        return result;

    }

   
}
